#include "zone.h"
#include <GL/glut.h>
#include <cmath>
#include "elements/scene/Textures.h"

extern BMPClass textureImages[4];
extern GLuint texture[4];

void colorize(float val,float seaLevel,float z)
{
	glColor3f(0.2-1.2*abs(val-seaLevel)/z+0.01,0.2-1.2*abs(val-seaLevel)/z+0.5,0.2-1.2*abs(val-seaLevel)/z-0.01);
}

void Zone::calculateMap()
{

	terrain.resize(map.getHeightMap().size());
	for(int i=0;i<map.getHeightMap().size();i++)
	{
		terrain[i].resize(map.getHeightMap()[i].size());
	}

	for(unsigned int i=0; i<map.getHeightMap().size(); i++)
	{
		for(unsigned int j=0; j<map.getHeightMap()[i].size(); j++)
		{
			terrain[i][j]=fromHeighttoMap(make_pair(i,j));
		}
	}
}

void Zone::draw()
{
	float mapx=map.getMapDimensionX();
	float mapy=map.getMapDimensionY();
	float mapz=map.getMapDimensionZ();
	float seaz=map.getSeaLevel()*map.getMapDimensionZ()/255.0;

	//Draw SkyBox
	glColor3f(1,1,1);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);
	if(dayMode==DAY)
		glBindTexture(GL_TEXTURE_2D, Textures::textureIds[2]);
	else if(dayMode==NIGHT)
		glBindTexture(GL_TEXTURE_2D, Textures::textureIds[3]);
	glBegin(GL_QUADS);
	{
		//front
		glTexCoord2f(0,0.5);		glVertex3f(0,0,-mapz);
		glTexCoord2f(0,0.75);		glVertex3f(0,0,4*mapz);
		glTexCoord2f(0.25,0.75);	glVertex3f(mapx,0,4*mapz);
		glTexCoord2f(0.25,0.5);		glVertex3f(mapx,0,-mapz);

		//right
		glTexCoord2f(0.25,0.5);		glVertex3f(mapx,0,-mapz);
		glTexCoord2f(0.25,0.75);	glVertex3f(mapx,0,4*mapz);
		glTexCoord2f(0.5,0.75);		glVertex3f(mapx,mapy,4*mapz);
		glTexCoord2f(0.5,0.5);		glVertex3f(mapx,mapy,-mapz);

		//back
		glTexCoord2f(0.5,0.5);		glVertex3f(mapx,mapy,-mapz);
		glTexCoord2f(0.5,0.75);		glVertex3f(mapx,mapy,4*mapz);
		glTexCoord2f(0.75,0.75);	glVertex3f(0,mapy,4*mapz);
		glTexCoord2f(0.75,0.5);		glVertex3f(0,mapy,-mapz);

		//left
		glTexCoord2f(0.75,0.5);		glVertex3f(0,mapy,-mapz);
		glTexCoord2f(0.75,0.75);	glVertex3f(0,mapy,4*mapz);
		glTexCoord2f(1,0.75);		glVertex3f(0,0,4*mapz);
		glTexCoord2f(1,0.5);		glVertex3f(0,0,-mapz);

		//up
		glTexCoord2f(0.5,0.75);		glVertex3f(mapx,mapy,4*mapz);
		glTexCoord2f(0.5,1);		glVertex3f(mapx,0,4*mapz);
		glTexCoord2f(0.75,1);		glVertex3f(0,0,4*mapz);
		glTexCoord2f(0.75,0.75);	glVertex3f(0,mapy,4*mapz);

		//down
		glTexCoord2f(0.5,0.75);		glVertex3f(mapx,mapy,-mapz);
		glTexCoord2f(0.5,1);		glVertex3f(mapx,0,-mapz);
		glTexCoord2f(0.75,1);		glVertex3f(0,0,-mapz);
		glTexCoord2f(0.75,0.75);	glVertex3f(0,mapy,-mapz);


	}
	glEnd();
	glDisable(GL_TEXTURE_2D);


	glEnable(GL_LIGHTING);

	//Draw Terrain
	pair<float,float> tmpDim;
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, Textures::textureIds[1]);


	//Draw Boundaries
	colorize(0,seaz,mapz);
	glBegin(GL_QUADS);
	{
		//front
		glTexCoord2f(0,0);		glVertex3f(5,5,-mapz);
		glTexCoord2f(0,1);		glVertex3f(5,5,seaz);
		glTexCoord2f(1,1);		glVertex3f(mapx-5,5,seaz);
		glTexCoord2f(1,0);		glVertex3f(mapx-5,5,-mapz);

		//right
		glTexCoord2f(0,0);		glVertex3f(mapx-5,5,-mapz);
		glTexCoord2f(0,1);		glVertex3f(mapx-5,5,seaz);
		glTexCoord2f(1,1);		glVertex3f(mapx-5,mapy-5,seaz);
		glTexCoord2f(1,0);		glVertex3f(mapx-5,mapy-5,-mapz);

		//back
		glTexCoord2f(0,0);		glVertex3f(mapx-5,mapy-5,-mapz);
		glTexCoord2f(0,1);		glVertex3f(mapx-5,mapy-5,seaz);
		glTexCoord2f(1,1);		glVertex3f(5,mapy-5,seaz);
		glTexCoord2f(1,0);		glVertex3f(5,mapy-5,-mapz);

		//left
		glTexCoord2f(0,0);		glVertex3f(5,mapy-5,-mapz);
		glTexCoord2f(0,1);		glVertex3f(5,mapy-5,seaz);
		glTexCoord2f(1,1);		glVertex3f(5,5,seaz);
		glTexCoord2f(1,0);		glVertex3f(5,5,-mapz);
	}
	glEnd();


	glBegin(GL_TRIANGLES);
	glNormal3f(0,0,1);
	glColor3d(1,1,1);
	for(unsigned int i=0; i<map.getHeightMap().size(); i++)
	{
		for(unsigned int j=0; j<map.getHeightMap()[i].size(); j++)
		{
			if(i==map.getHeightMap().size()-1 || j==map.getHeightMap()[i].size()-1)
				continue;


			tmpDim=fromHeighttoMap(make_pair(i,j+1));
			colorize(map.getHeightMap()[i][j+1],seaz,mapz);
			glTexCoord2f(0,0); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i][j+1]);

			tmpDim=fromHeighttoMap(make_pair(i,j));
			colorize(map.getHeightMap()[i][j],seaz,mapz);
			glTexCoord2f(0,1); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i][j]);

			tmpDim=fromHeighttoMap(make_pair(i+1,j));
			colorize(map.getHeightMap()[i+1][j],seaz,mapz);
			glTexCoord2f(1,1); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i+1][j]);


			tmpDim=fromHeighttoMap(make_pair(i+1,j+1));
			colorize(map.getHeightMap()[i+1][j+1],seaz,mapz);
			glTexCoord2f(0,0); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i+1][j+1]);

			tmpDim=fromHeighttoMap(make_pair(i,j+1));
			colorize(map.getHeightMap()[i][j+1],seaz,mapz);
			glTexCoord2f(0,1); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i][j+1]);

			tmpDim=fromHeighttoMap(make_pair(i+1,j));
			colorize(map.getHeightMap()[i+1][j],seaz,mapz);
			glTexCoord2f(1,1); glVertex3f(tmpDim.first,tmpDim.second,map.getHeightMap()[i+1][j]);

		}
	}
	glEnd();
	glDisable(GL_TEXTURE_2D);


	//Draw Bonus Packs
	for(unsigned int i=0;i<packs.size();i++)
		packs[i].draw3d(seaz);


	//Draw Water
	glEnable(GL_BLEND);					// Turn Blending On
	glBlendFunc(GL_ONE, GL_SRC_ALPHA);	// Set The Blending Function For Translucency

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, Textures::textureIds[0]);

	glBegin(GL_QUADS);
	glColor4f(1,1,1,0.3);
	glNormal3f(0,0,1);
	for(int i=0;i<mapx/9;i++)
	{
		for(int j=0;j<mapy/9;j++)
		{
			glTexCoord2f(0,0);  glVertex3f((i)*9,(j)*9,seaz);
			glTexCoord2f(1,0);	glVertex3f((i+1)*9,(j)*9,seaz);
			glTexCoord2f(1,1);	glVertex3f((i+1)*9,(j+1)*9,seaz);
			glTexCoord2f(0,1);	glVertex3f((i)*9,(j+1)*9,seaz);
		}
	}
	glEnd();

/*	//glColor4f(0,0,0.7,0.9);
	glColor3f(0.9,0.9,1);
	glBegin(GL_QUADS);
	{
		float xtex = mapx/128.0;
		float ytex = mapy/128.0;
		glTexCoord2f(0,0);  	glVertex3f(0,0,seaz);
		glTexCoord2f(xtex,0);	glVertex3f(mapx,0,seaz);
		glTexCoord2f(xtex,ytex);glVertex3f(mapx,mapy,seaz);
		glTexCoord2f(0,ytex);	glVertex3f(0,mapy,seaz);
	}
	glEnd();*/

	glDisable(GL_TEXTURE_2D);

	glDisable(GL_BLEND);

}







pair<float,float> Zone::fromWindowtoMap(pair<float,float> tmp)
{
	float x;//=tmp.first*(right-left)/800.0+left;
	float y;//=tmp.second*(bottom-top)/600+top;

	return make_pair(x,y);
}

pair<float,float> Zone::fromHeighttoMap(pair<float,float> tmp)
{
	float tmpX=((float)tmp.first+0.5)*map.getMapDimensionX()/(float)map.getHeightMapWidth();
	float tmpY=((float)tmp.second+0.5)*map.getMapDimensionY()/(float)map.getHeightMapHeight();
	return make_pair(tmpX,tmpY);
}

pair<int,int> Zone::fromMaptoHeight(pair<float,float> tmp)
{
	int tmpX=tmp.first*map.getHeightMapWidth()/map.getMapDimensionX();
	int tmpY=tmp.second*map.getHeightMapHeight()/map.getMapDimensionY();
	return make_pair(tmpX,tmpY);
}

pair<int,int> Zone::fromWindowtoHeight(pair<float,float> tmp)
{
	return fromMaptoHeight(fromWindowtoMap(tmp));
}
